#pragma once

#include "base_view_model.h"
#include "application/simulation/simulation_service.h"
#include "application/vehicle/vehicle_service.h"
#include "application/task/task_service.h"
#include <QObject>
#include <QString>
#include <memory>

namespace presentation {
namespace viewmodels {

/**
 * @brief 仿真器 ViewModel
 * @details 连接 SimulationService 和 QML 界面，提供仿真控制和状态展示
 */
class SimulatorViewModel : public BaseViewModel {
    Q_OBJECT

    // ==================== 仿真状态 ====================
    Q_PROPERTY(bool isPlaying READ isPlaying NOTIFY simulationStateChanged)
    Q_PROPERTY(bool isPaused READ isPaused NOTIFY simulationStateChanged)
    Q_PROPERTY(double simulationTime READ simulationTime NOTIFY simulationTimeChanged)
    Q_PROPERTY(double timeScale READ timeScale WRITE setTimeScale NOTIFY timeScaleChanged)
    Q_PROPERTY(bool isEnabled READ isEnabled NOTIFY enabledChanged)

    // ==================== 场景信息 ====================
    Q_PROPERTY(QString scenarioName READ scenarioName NOTIFY scenarioChanged)
    Q_PROPERTY(QString duration READ duration NOTIFY simulationTimeChanged)

    // ==================== KPI 指标 ====================
    Q_PROPERTY(int completedTaskCount READ completedTaskCount NOTIFY kpiChanged)
    Q_PROPERTY(int failedTaskCount READ failedTaskCount NOTIFY kpiChanged)
    Q_PROPERTY(int conflictCount READ conflictCount NOTIFY kpiChanged)
    Q_PROPERTY(int onlineVehicleCount READ onlineVehicleCount NOTIFY kpiChanged)
    Q_PROPERTY(int idleVehicleCount READ idleVehicleCount NOTIFY kpiChanged)
    Q_PROPERTY(double taskCompletionRate READ taskCompletionRate NOTIFY kpiChanged)

public:
    // Default constructor for QML
    explicit SimulatorViewModel(QObject* parent = nullptr);

    // Constructor with service injection
    explicit SimulatorViewModel(
        std::shared_ptr<application::simulation::SimulationService> simulationService,
        application::vehicle::VehicleService* vehicleService,
        application::task::TaskService* taskService,
        QObject* parent = nullptr);

    ~SimulatorViewModel() override = default;

    // Override BaseViewModel methods
    void initialize() override;
    void cleanup() override;

    // ==================== 属性访问器 ====================

    // 仿真状态
    bool isPlaying() const { return m_isPlaying; }
    bool isPaused() const { return m_isPaused; }
    double simulationTime() const { return m_simulationTime; }
    double timeScale() const { return m_timeScale; }
    bool isEnabled() const { return m_isEnabled; }

    // 场景信息
    QString scenarioName() const { return m_scenarioName; }
    QString duration() const;

    // KPI 指标
    int completedTaskCount() const { return m_completedTaskCount; }
    int failedTaskCount() const { return m_failedTaskCount; }
    int conflictCount() const { return m_conflictCount; }
    int onlineVehicleCount() const { return m_onlineVehicleCount; }
    int idleVehicleCount() const { return m_idleVehicleCount; }
    double taskCompletionRate() const;

    // ==================== 仿真控制命令 ====================

    /**
     * @brief 播放仿真
     */
    Q_INVOKABLE void play();

    /**
     * @brief 暂停仿真
     */
    Q_INVOKABLE void pause();

    /**
     * @brief 恢复仿真（从暂停状态）
     */
    Q_INVOKABLE void resume();

    /**
     * @brief 停止仿真（重置时间）
     */
    Q_INVOKABLE void stop();

    /**
     * @brief 单步推进
     * @param deltaTime 推进时间量（秒）
     */
    Q_INVOKABLE void step(double deltaTime = 0.1);

    /**
     * @brief 设置时间缩放
     * @param scale 时间缩放倍率（0.5x ~ 5.0x）
     */
    void setTimeScale(double scale);

    /**
     * @brief 重置所有统计数据
     */
    Q_INVOKABLE void resetStatistics();

    /**
     * @brief 加载场景
     * @param scenarioName 场景名称
     */
    Q_INVOKABLE void loadScenario(const QString& scenarioName);

    /**
     * @brief 重置所有仿真车辆到初始位置
     */
    Q_INVOKABLE void resetSimulationVehicles();

signals:
    void simulationStateChanged();
    void simulationTimeChanged();
    void timeScaleChanged();
    void enabledChanged();
    void scenarioChanged();
    void kpiChanged();

private slots:
    void onSimulationTimeChanged(double time);
    void onSimulationStateChanged(bool isPlaying, bool isPaused);
    void onVehicleStatusChanged(int agvNumber);
    void updateKpiMetrics();

private:
    // 服务依赖
    std::shared_ptr<application::simulation::SimulationService> m_simulationService;
    application::vehicle::VehicleService* m_vehicleService;
    application::task::TaskService* m_taskService;

    // 仿真状态
    bool m_isPlaying{false};
    bool m_isPaused{false};
    double m_simulationTime{0.0};
    double m_timeScale{1.0};
    bool m_isEnabled{false};

    // 场景信息
    QString m_scenarioName;

    // KPI 指标
    int m_completedTaskCount{0};
    int m_failedTaskCount{0};
    int m_conflictCount{0};
    int m_onlineVehicleCount{0};
    int m_idleVehicleCount{0};

    // 内部方法
    void connectSignals();
    void updateVehicleStatistics();
    void updateTaskStatistics();
};

} // namespace viewmodels
} // namespace presentation
